'''
Case Type： 文件目录
Case Name： 配置文件丢失恢复，备机重建后，主停服备升主
Create At:  2020/07/24
Owner    :  @li-xin12345
Descption:  1.备机删除配置文件 2.备机重建 3.恢复配置文件 4.备机重建 5.查看主备状态 6.主停服 7.备升主 8.新主节点执行以下指令刷新：
            9.查看主备状态 10.新主节点运行tpcc指令 11.重启 12.备节点执行，主备切换 13.主节点执行，刷新
'''

import os
import sys
import unittest
import time
from yat.test import Node
from yat.test import macro

sys.path.append(sys.path[0] + "/../")

from testcase.utils.CommonSH import *
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common

logger = Logger()


class IndexFileDamaged(unittest.TestCase):
    primary_sh = CommonSH('PrimaryDbUser')
    standby_1_sh = CommonSH('Standby1DbUser')
    standby_2_sh = CommonSH('Standby2DbUser')
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        logger.info('------------Opengauss_Reliability_Dbsys_Case180.py start------------')
        # 此用例中主备节点定义切换，为了构造拥有TPCC的备机
        self.db_standby_1_root = Node('Standby1Root')
        self.db_standby_1_user = Node(node='Standby1DbUser')
        self.db_primary_root = Node(node='PrimaryRoot')
        self.db_primary_user = Node(node='PrimaryDbUser')
        self.DB_ENV_PATH = macro.DB_ENV_PATH
        self.DB_INSTANCE_PATH = macro.DB_INSTANCE_PATH
        self.DB_MY_PATH = macro.DB_BACKUP_PATH
        self.TPCC_PATH = macro.TPCC_PATH
        self.Constant = Constant()
        self.com = Common('PrimaryDbUser')

        self.hostmsg = self.db_primary_user.sh('hostname;').result()
        logger.info(f'hostname is {self.hostmsg}')

    def test_Index_file_damaged(self):
        # 用例开始，备机删除配置文件
        logger.info('-----------------------备机移除配置文件---------------------------')
        excute_cmd = f'mv {self.DB_INSTANCE_PATH}/{macro.DB_PG_CONFIG_NAME} {self.DB_INSTANCE_PATH}/{macro.DB_PG_CONFIG_NAME}.baktest'
        logger.info(excute_cmd)
        msg = self.db_standby_1_user.sh(excute_cmd).result()
        logger.info(msg)
        self.assertNotIn(self.Constant.SQL_WRONG_MSG[1], msg)

        logger.info('-----------------------进行备机重建-----------------------------------')
        buildMsg = self.standby_1_sh.executeGsctl('build', self.Constant.BUILD_FAIL_MSG, '-b full')
        self.assertFalse(buildMsg)

        logger.info('-----------------------恢复配置文件---------------------------')
        excute_cmd = f'mv {self.DB_INSTANCE_PATH}/{macro.DB_PG_CONFIG_NAME}.baktest {self.DB_INSTANCE_PATH}/{macro.DB_PG_CONFIG_NAME}'
        logger.info(excute_cmd)
        msg = self.db_standby_1_user.sh(excute_cmd).result()
        logger.info(msg)
        self.assertNotIn(self.Constant.SQL_WRONG_MSG[1], msg)

        logger.info('-----------------------再次进行备机重建-----------------------------------')
        buildMsg = self.standby_1_sh.executeGsctl('build', self.Constant.REBUILD_SUCCESS_MSG, '-b full')
        self.assertTrue(buildMsg)

        logger.info('-----------------------查看主备状态---------------------------')
        status = self.primary_sh.getDbClusterStatus('status')
        self.assertTrue(status)

        logger.info('-----------------------进行主停服---------------------------')
        msg = self.primary_sh.stopDbInstance()
        logger.info(msg)

        logger.info('-----------------------查看主备状态---------------------------')
        self.primary_sh.getDbClusterStatus('status')

        logger.info('-----------------------进行备升主---------------------------')
        msg = self.standby_1_sh.executeGsctl('failover', self.Constant.FAILOVER_SUCCESS_MSG)
        self.assertTrue(msg)

        logger.info('-----------------------新主节点执行以下指令刷新---------------------------')
        msg = self.standby_1_sh.exec_refresh_conf()
        self.assertTrue(msg)

        logger.info('-----------------------查看主备状态---------------------------')
        self.standby_1_sh.startDbCluster()
        status = self.standby_1_sh.getDbClusterStatus('status')
        self.assertTrue(status)

        logger.info('-----------------------执行TPCC---------------------------')
        tpcc_result = self.com.startTPCC(self.db_standby_1_root, self.TPCC_PATH)
        logger.info(tpcc_result)
        self.assertIn(self.Constant.TPCC_SUCCESS_MSG, tpcc_result)

        # 校验刷脏页是否完成
        logger.info('校验刷脏页是否完成')
        dirty_page_finshed_flag = self.standby_1_sh.check_whether_remain_dirty_page()
        self.assertTrue(dirty_page_finshed_flag)

        # 校验备机是否完成数据同步
        logger.info('校验备机是否完成数据同步')
        flag_1 = self.primary_sh.check_data_consistency()
        self.assertTrue(flag_1)
        flag_2 = self.standby_2_sh.check_data_consistency()
        self.assertTrue(flag_2)

        logger.info('-----------------------主备切换-恢复数据库---------------------------')
        msg = self.primary_sh.executeGsctl('switchover', self.Constant.SWITCHOVER_SUCCESS_MSG)
        self.assertTrue(msg)

        logger.info('-----------------------执行以下指令刷新---------------------------')
        msg = self.primary_sh.exec_refresh_conf()
        self.assertTrue(msg)

        logger.info('-----------------------查看主备状态---------------------------')
        msg = self.primary_sh.getDbClusterStatus('status')
        self.assertTrue(msg)

    def tearDown(self):
        logger.info('----------------------------后置处理-----------------------------')
        status = self.primary_sh.check_whether_need_switch(self.hostmsg)
        if status:
            self.primary_sh.executeGsctl('switchover', self.Constant.SWITCHOVER_SUCCESS_MSG)
            self.primary_sh.exec_refresh_conf()
        status = self.primary_sh.check_whether_need_build()
        if status:
            self.standby_1_sh.executeGsctl('build', self.Constant.BUILD_SUCCESS_MSG, '-b full')
            self.standby_2_sh.executeGsctl('build', self.Constant.BUILD_SUCCESS_MSG, '-b full')
        logger.info('----------------------------Reliability_Dbsys_Case180执行完成-----------------------------')
